package com.yong.automoguding.task;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.yong.automoguding.component.BullshitGenerator;
import com.yong.automoguding.constant.MogudingConstant;
import com.yong.automoguding.context.MogudingContext;
import com.yong.automoguding.dto.MogudingClockRequest;
import com.yong.automoguding.dto.MogudingDaily;
import com.yong.automoguding.dto.MogudingResponse;
import com.yong.automoguding.entity.UserInfo;
import com.yong.automoguding.entity.UserLog;
import com.yong.automoguding.exception.MogudingException;
import com.yong.automoguding.remote.MogudingApi;
import com.yong.automoguding.service.IUserInfoService;
import com.yong.automoguding.service.IUserLogService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import retrofit2.Call;
import retrofit2.Response;

import java.io.IOException;
import java.time.LocalDateTime;
import java.util.*;

/**
 * 打卡任务
 *
 * @author Hes
 */
@Component
@Slf4j
public class MogudingClockTask implements IScheduledTask {

    @Autowired
    private MogudingApi mogudingApi;

    @Autowired
    private IUserInfoService userInfoService;

    @Autowired
    private IUserLogService userLogService;

    public void login(MogudingContext context) {
        Map<String, Object> loginInfo = new HashMap<>(16);
        loginInfo.put("password", context.getPassword());
        loginInfo.put("phone", context.getPhone());
        loginInfo.put("loginType", "android");
        loginInfo.put("uuid", "");
        MogudingResponse body = mogudingApi.login(loginInfo);

        if (!Objects.equals(MogudingConstant.CODE_SUCCESS, body.getCode())) {
            throw new MogudingException(body.getMsg());
        }
        context.setToken((String) ((Map)body.getData()).get("token"));

        UserInfo userInfo = new UserInfo();
        userInfo.setId(context.getId());
        userInfo.setToken(context.getToken());
        userInfoService.saveOrUpdate(userInfo);

    }

    public void getPlanId(MogudingContext context, int retryCount) {
        if (StringUtils.hasLength(context.getPlanId())) {
            return;
        }
        Map<String, Object> data = new HashMap<>(1);
        Map<String, String> headers = new HashMap<>(1);
        data.put("state", "");
        headers.put("Authorization", context.getToken());
        MogudingResponse response = mogudingApi.getPlanByStu(data, headers);

        if (!Objects.equals(MogudingConstant.CODE_SUCCESS, response.getCode())) {
            if (retryCount > MogudingConstant.MAX_RETRY_COUNT) {
                throw new MogudingException("请求失败,"+response.getMsg());
            }
            login(context);
            getPlanId(context, retryCount + 1);
            return;
        }
        List<?> responseData = (List) response.getData();
        Map map = (Map) responseData.get(0);
        String planId = (String) map.get("planId");
        context.setPlanId(planId);

        UserInfo userInfo = new UserInfo();
        userInfo.setId(context.getId());
        userInfo.setPlanId(planId);
        userInfoService.saveOrUpdate(userInfo);

    }


    public void clock(MogudingContext context, String type ,int retryCount) {
        if (!StringUtils.hasLength(context.getToken())) {
            login(context);
        }
        MogudingClockRequest request = new MogudingClockRequest();
        request.setType(type);
        request.setPlanId(context.getPlanId());
        request.setAddress(context.getAddress());
        request.setLatitude(context.getLatitude());
        request.setLongitude(context.getLongitude());
        Map<String, String> header = new HashMap<>(2);
        header.put("Authorization", context.getToken());
        header.put("roleKey", "student");
        MogudingResponse response = mogudingApi.clock(request, header);

        if (!Objects.equals(MogudingConstant.CODE_SUCCESS, response.getCode())) {
            if (retryCount > MogudingConstant.MAX_RETRY_COUNT) {
                throw new MogudingException("请求失败,"+response.getMsg());
            }
            login(context);
            clock(context, type, retryCount + 1);
            return;
        }

        UserLog userLog = new UserLog();
        userLog.setUserId(context.getId());
        userLog.setLogType(type);
        userLogService.save(userLog);

    }

    public void daily(MogudingContext context, int retryCount) {
        if (!StringUtils.hasLength(context.getToken())) {
            login(context);
        }
        Map<String, String> header = new HashMap<>(2);
        header.put("Authorization", context.getToken());
        header.put("roleKey", "student");
        MogudingDaily daily = new MogudingDaily();
        daily.setContent(BullshitGenerator.bullshit("实习日报", 233));
        daily.setPlanId(context.getPlanId());
        MogudingResponse body = mogudingApi.daily(daily, header);

        if (!Objects.equals(body.getCode(), MogudingConstant.CODE_SUCCESS)) {
            if (retryCount > MogudingConstant.MAX_RETRY_COUNT) {
                throw new RuntimeException("请求失败:"+body.getMsg());
            }
            daily(context,retryCount + 1);
            return;
        }

        UserLog userLog = new UserLog();

        userLog.setComment(daily.getContent());
        userLog.setUserId(context.getId());
        userLog.setLogType(MogudingConstant.DAILY);
        userLogService.save(userLog);

    }

    @Override
    public void run()  {
        List<UserInfo> list = userInfoService.list();
        list.forEach(userInfo -> {
            MogudingContext context = new MogudingContext();
            context.setId(userInfo.getId());
            context.setPhone(userInfo.getUsername());
            context.setToken(userInfo.getToken());
            context.setPassword(userInfo.getPassword());
            context.setPlanId(userInfo.getPlanId());
            context.setAddress(userInfo.getAddress());
            context.setLatitude(userInfo.getLatitude());
            context.setLongitude(userInfo.getLongitude());
            context.setNeedPost(userInfo.getNeedPost());
            try {
                getPlanId(context,0);
                clock(context, MogudingConstant.START,0);
                clock(context, MogudingConstant.END,0);
                // 是否上报可配置
                if (context.getNeedPost() != null && context.getNeedPost()) {
                    daily(context, 0);
                }
            } catch (Exception e) {
                log.error("task error context: {}", context);
                log.error("task error:", e);
            }
        });



    }


}
